package com.ys.chatserver.http.logic;

import com.alibaba.fastjson.JSONObject;
import com.eva.framework.Processor;
import com.eva.framework.dbpool.DBDepend;
import com.eva.framework.dto.SysActionConst;
import com.eva.framework.utils.EndsExceptionFactory;
import com.google.gson.Gson;
import com.ys.chatserver.http.logic.dto.JobDispatchConst;
import com.ys.chatserver.im.dto.GpsDTO;
import com.ys.chatserver.im.impl.GpsManager;
import com.ys.chatserver.tool.EmptyUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class GpsProcessor implements SysActionConst, Processor {

    private ConcurrentHashMap<String, List<String>> subList = new ConcurrentHashMap<>();

    @Override
    public Object process(int job_dispatch_id, int action_id, Object _newData, Object _oldData, User user) throws Exception {
        Object ret = null;
        String newDataJSON = (String) _newData;

        // 处理客户端上传的gps定位消息
        if (job_dispatch_id == JobDispatchConst.LOGIC_GPS_MGR) {
            ret = maintainMgrGpsJobDispatcher(action_id, newDataJSON, _oldData, user);
        } else {
            throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
        }
        return ret;
    }


    private Object maintainMgrGpsJobDispatcher(int action_id, String newDataJSON
            , Object oldData, User user) throws Exception {
        Vector<Object> sqls = new Vector<>(2);
        Vector<Object> values = new Vector<>(2);
        switch (action_id) {
            /** 定位上报 接口【1018-27-7】*/
            case ACTION_APPEND1: {
                JSONObject nwObj = JSONObject.parseObject(newDataJSON);
                //上报者用户Id
                final String userUid = nwObj.getString("user_uid");
                //经度
                final String lng = nwObj.getString("lng");
                //纬度
                final String lat = nwObj.getString("lat");
                insertUserGps(sqls, values, userUid, lat, lng);
                boolean update = LogicProcessor2.db.update(sqls, values, true);
                List<String> list = subList.get(userUid);
                if (EmptyUtils.isNotEmpty(list)) {
                    for (String str : list) {
                        GpsManager.batchNotificationGps(str, userUid, lat, lng);
                    }
                }
                return update ? "1" : "0";
            }
            /** 定位订阅 接口【1018-27-8】*/
            case ACTION_APPEND2: {
                JSONObject nwObj = JSONObject.parseObject(newDataJSON);
                //上报者用户Id
                final String userUid = nwObj.getString("user_uid");
                final String userList = nwObj.getString("user_list");
                subsribeByUser(userUid, EmptyUtils.getListObjectSplitValue(userList));
                return "1";
            }
            /** 定位取消订阅 接口【1018-27-9】*/
            case ACTION_APPEND3: {
                JSONObject nwObj = JSONObject.parseObject(newDataJSON);
                //上报者用户Id
                final String userUid = nwObj.getString("user_uid");
                final String userList = nwObj.getString("user_list");
                unSubsribeByUser(userUid, EmptyUtils.getListObjectSplitValue(userList));
                return "1";
            }
            /** 查询gps点*/
            case ACTION_QUERY_GPS: {
                JSONObject nwObj = JSONObject.parseObject(newDataJSON);
                //上报者用户Id
                final String userUid = nwObj.getString("user_uid");
                final String groupId = nwObj.getString("group_id");
                final String startTime = nwObj.getString("start_time");
                final String endTime = nwObj.getString("end_time");
                return queryGps(userUid, groupId, startTime, endTime);
            }

            /** 查询gps点*/
            case ACTION_HISTORY_GPS: {
                JSONObject nwObj = JSONObject.parseObject(newDataJSON);
                //上报者用户Id
                final String userUid = nwObj.getString("user_uid");
                final String groupId = nwObj.getString("group_id");
                final String startTime = nwObj.getString("start_time");
                final String endTime = nwObj.getString("end_time");

                return queryHistoryGps(userUid, groupId, startTime, endTime);
            }

            default:
                throw EndsExceptionFactory.INVALID_ACTION_ID(action_id);
        }
    }

    private String queryGps(String userUid, String groupId, String startTime, String endTime) throws Exception {
        String sql = "select gps_lat,gps_lng from t_gps where (create_time BETWEEN '"
                + startTime + "' AND '" + endTime + "') and gps_uid = '" + userUid + "'";
        if (EmptyUtils.isNotEmpty(groupId)) {
            sql = sql + " and group_id = '" + groupId + "'";
        }
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        List<GpsDTO> dtos = new ArrayList<>();
        if (!vectors.isEmpty()) {
            for (Vector<?> vector : vectors) {
                String gpsLat = vector.get(0).toString();
                String gpsLng = vector.get(1).toString();
                GpsDTO dto = new GpsDTO();
                dto.setGpsLat(gpsLat);
                dto.setGpsLng(gpsLng);
                dtos.add(dto);
            }
        }
        return new Gson().toJson(dtos);
    }

    private String queryHistoryGps(String userUid, String groupId, String startTime, String endTime) throws Exception {

        String sql = "select gps_lat,gps_lng,create_time from t_gps where gps_uid = '" + userUid + "'";
        if (EmptyUtils.isNotEmpty(startTime)) {
            sql = sql + " and create_time > '" + startTime + "'";
        }
        if (EmptyUtils.isNotEmpty(endTime)) {
            sql = sql + " and create_time < '" + endTime + "'";
        }
        if (EmptyUtils.isNotEmpty(groupId)) {
            if (groupId.contains("_")) {
                groupId = groupId.split("_")[0];
            }
            sql = sql + " and group_id = '" + groupId + "'";
        }
        sql = sql + " order by create_time asc";
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        List<GpsDTO> dtos = new ArrayList<>();
        if (!vectors.isEmpty()) {
            for (Vector<?> vector : vectors) {
                String gpsLat = vector.get(0).toString();
                String gpsLng = vector.get(1).toString();
                String createTime = vector.get(2).toString();
                GpsDTO dto = new GpsDTO();
                dto.setGpsLat(gpsLat);
                dto.setGpsLng(gpsLng);
                dto.setCreateTime(createTime);
                dtos.add(dto);
            }
        }
        return new Gson().toJson(dtos);
    }

    /**
     * 插入上报经纬度
     *
     */
    public void insertUserGps(Vector<Object> sqls, Vector<Object> values, String userUid, String lat, String lng) {
        sqls.add("INSERT INTO t_gps(gps_uid,gps_lat,gps_lng,create_time" +
                ") VALUES(?,?,?," + DBDepend.getDefaultDatetimeFunc() + ")");
        values.add(new Object[]{userUid, lat, lng});
    }

    /**
     * gps订阅
     *
     */
    public void subsribeByUser(String user_uid, List<String> userList) {
        for (String str : userList) {
            if (subList.containsKey(str)) {
                List<String> list = new ArrayList<>(subList.get(str));
                list.add(user_uid);
                subList.replace(str, list);
            } else {
                subList.put(str, Collections.singletonList(user_uid));
            }
        }
    }

    /**
     * gps取消订阅
     *
     */
    public void unSubsribeByUser(String user_user, List<String> userList) {
        for (String str : userList) {
            if (subList.containsKey(str)) {
                List<String> list = new ArrayList<>(subList.get(str));
                list.remove(user_user);
                subList.replace(str, list);
            }
        }
    }
}
